﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpAdbClient;
using System.Drawing;
using System.Threading.Tasks;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;
using DroidLord.Task;
using DroidLord.Core;
using System.IO;
using System.Windows.Forms;
using DroidLord.Util;

namespace DroidLord.Slavery
{
    public enum DroidKey
    {
        HOME = 3,
        BACK = 4,
        MENU = 1,
        V_UP = 24,
        V_DOWN = 25,
        POWER = 26
    }

    public class Manipulate :IShellOutputReceiver
    {
        private Slave slave;
        private Socket client;

        public bool ParsesErrors
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        public Manipulate(Slave slave)
        {
            this.slave = slave;
            var adb =new  AdbClient();
            client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            new Thread(() =>
            {
                try
                {
                    new AdbClient().ExecuteRemoteCommand($"/data/local/tmp/minitouch", slave.Device, this);
                }catch(Exception eeee)
                {

                }
            })
            { IsBackground = true }.Start();
            try
            {
                client.Connect(IPAddress.Loopback, slave.ManipulatePort);
            }catch(Exception eeee)
            {

            }
            //sendCommand("hello", () => {
            //    Thread.Sleep(1000);
            //    sendCommand("world",()=> Touch(Point.Empty));
            //});            
        }

        void sendCommand(string cmd, ThreadStart finished = null)
        {
            new Thread(() =>
            {
                while (true)
                {
                    try
                    {
                        if (!client.Connected)
                        {
                            client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                            client.Connect(IPAddress.Loopback, slave.ManipulatePort);
                        }
                        var buffer = Encoding.UTF8.GetBytes(cmd);
                        client.Send(buffer);
                        break;
                    }
                    catch (Exception ex)
                    {                        
                        Thread.Sleep(200);
                        Debug.WriteLine(ex.ToString());
                        //Program.Logs.WriteLog("无法连接远程操纵端口", ex.Message, Core.LogLevel.Exception);
                    }
                    finally
                    {
                      
                    }                   
                }
                // 处理完成回调
                if (finished != null)
                {
                    finished.Invoke();
                }
            })
            { IsBackground = true }.Start();
        }

        public void TouchDown(Point poi)
        {
            sendCommand($"d 0 {poi.X} {poi.Y} 255\nc\n");
            Debug.WriteLine($"POI:{poi.X}/{poi.Y} | {poi.X / (double)slave.ScreenService.Width}/{poi.Y / (double)slave.ScreenService.Height}");
        }


       


        public void Touch(Point poi, ThreadStart finished = null) 
        {
            sendCommand($"d 0 {poi.X} {poi.Y} 255\nc\n",
                () =>
                {
                    Thread.Sleep(32);
                    sendCommand($"u 0 {poi.X} {poi.Y} 255\nc\n", () =>
                    {
                        if (finished != null)
                        {
                            finished.Invoke();
                        }
                    });
                });
        }
        public void TouchMove(Point poi)
        {
            sendCommand($"m 0 {poi.X} {poi.Y} 255\nc\n");
        }
        public void TouchUp(Point poi)
        {
            sendCommand($"u 0 {poi.X} {poi.Y} 255\nc\n");
            Debug.WriteLine($"POI:{poi.X}/{poi.Y} | {poi.X / (double)slave.ScreenService.Width}/{poi.Y / (double)slave.ScreenService.Height}");
        }

        public void Keypress(DroidKey key)
        {
            Dispatcher.BackgroundThread(() =>
                new AdbClient()
                        .ExecuteRemoteCommand($"input keyevent {(int)key}", slave.Device, this));
        }                
        public void Keypress(string keyChar)
        {
            Dispatcher.BackgroundThread(() =>
              new AdbClient()
                        .ExecuteRemoteCommand($"input text {keyChar}", slave.Device, this));
        }




        public void ClearText()
        {
            Dispatcher.BackgroundThread(() =>
            {
                if (DeviceManager.isDeviceOnline(slave.Device.Serial))
                {
                    InputMethodManager inputManager = new InputMethodManager();
                    inputManager.clearText(slave.Device);
                }
            });
        }

        public void inputTap(Point poit)
        {
            Dispatcher.BackgroundThread(() =>
            {
                if (DeviceManager.isDeviceOnline(slave.Device.Serial))
                {
                    AdbManager.executeShellNoRead(slave.Device, "input tap " + poit.X+" "+poit.Y);
                }
            });
        }

        public void inputSwipe(Point p1,Point p2)
        {
            Dispatcher.BackgroundThread(() =>
            {
                if (DeviceManager.isDeviceOnline(slave.Device.Serial))
                {
                    AdbManager.executeShellNoRead(slave.Device, "input swipe " + p1.X + " " + p1.Y + " " + p2.X + " " + p2.Y);
                }
            });
        }


        private void invokeMethod(string copyText)
        {
            //Thread.Sleep(3000);
           
                Clipboard.SetDataObject(copyText, true);
           
        }

        public void  switchIme()
        {
            //开启线程安装输入法
            Dispatcher.BackgroundThread(() =>
            {

                if (DeviceManager.isDeviceOnline(slave.Device.Serial))
                {
                    InputMethodManager manager = new InputMethodManager();
                    Boolean isInstallIme = manager.IsInstalled(slave.Device, "com.android.myinputmethod");
                    Program.Logs.WriteLog("设备:" + slave.Device.Serial + " IsInstalledime " + isInstallIme);
                    if (!isInstallIme)
                    {
                        string apkPath = PathManager.getInputMethodApkPath();
                        manager.InstallApk(slave.Device, apkPath);

                    }
                    isInstallIme = manager.IsInstalled(slave.Device, "com.android.myinputmethod");
                    if (isInstallIme)
                    {
                        manager.enableIme(slave.Device, "com.android.myinputmethod/com.github.uiautomator.FastInputIME");
                        // AdbManager.adbShellNoRead(slave.Device, "am start -n  com.android.myinputmethod/com.github.uiautomator.MainActivity");
                    }
                    else
                    {
                        DialogUtils.showTipDialog("错误提示", "检测到同屏输入法未安装,请安装同屏输入法之后再操作");

                    }
                }
            });
        }

        public void pasteTextToPC()
        {
            Dispatcher.BackgroundThread(() =>
            {
                if (DeviceManager.isDeviceOnline(slave.Device.Serial))
                {
                    string cmd1 = "rm /sdcard/copy.txt";
                    AdbManager.executeShell(slave.Device, cmd1);
                    InputMethodManager inputMethodManager = new InputMethodManager();
                    inputMethodManager.pasteTextToPc(slave.Device);
                    ///sdcard/copy.txt
                    string tempath = PathManager.getTempDir() + "\\copy.txt";
                    if(File.Exists(tempath))
                    {
                        File.Delete(tempath);
                    }
                    //Thread.Sleep(2 * 1000);
                    //string cmd = "cat /sdcard/copy.txt";
                    //string msg=AdbManager.executeShell(slave.Device, cmd);
                    string copyText = "";
                    //string[] mylines = msg.Split(new char[] { '\r', '\n' });
                    //if(mylines!=null)
                    //{
                    //    foreach(string line in mylines)
                    //    {
                    //        if(line.Trim().StartsWith("TEXT:"))
                    //        {
                    //            copyText = line.Trim().Replace("TEXT:", "");
                    //            break;
                    //        }
                    //    }
                    //}
                    //if(!copyText.Equals(""))
                    //{
                    //    string decode = "";
                    //    byte[] bytes = Convert.FromBase64String(copyText);
                    //    try
                    //    {
                    //        copyText = Encoding.UTF8.GetString(bytes);
                    //    }
                    //    catch
                    //    {
                    //        copyText ="";
                    //    }
                    //}
                    //MessageBox.Show("复制手机信息成功,信息:"+copyText, "拷贝手机剪贴板提示", MessageBoxButtons.OKCancel);
                    //MessageBox.Show("复制手机信息:"+ copyText);
                    if (1 >0)
                    {
                        Thread.Sleep(2 * 1000);

                        AdbManager.adbPull(slave.Device, "/sdcard/copy.txt", tempath);
                        //using (SyncService service = new SyncService(new AdbSocket(new IPEndPoint(IPAddress.Loopback, AdbClient.AdbServerPort)), slave.Device))
                        //using (Stream stream = File.OpenWrite(tempath))
                        //{
                        //    try
                        //    {
                        //        service.Pull("/scard/copy.txt", stream, null, CancellationToken.None);
                        //    }
                        //    catch (Exception eeee)
                        //    {

                        //    }
                        //}
                        if (File.Exists(tempath))
                        {
                            FileInfo fileInfo = new FileInfo(tempath);
                            long len = fileInfo.Length;
                            if (len > 0)
                            {
                                try
                                {
                                    // 创建一个 StreamReader 的实例来读取文件 
                                    // using 语句也能关闭 StreamReader
                                    using (StreamReader sr = new StreamReader(tempath))
                                    {
                                        string line;
                                        string copytext = "";

                                        // 从文件读取并显示行，直到文件的末尾 
                                        while ((line = sr.ReadLine()) != null)
                                        {
                                            copyText += line + "\n";
                                        }
                                        sr.Close();
                                        string decode = "";
                                        byte[] bytes = Convert.FromBase64String(copyText.Replace("TEXT:",""));
                                        try
                                        {
                                            copyText = Encoding.UTF8.GetString(bytes);
                                        }
                                        catch
                                        {
                                            copyText = "";
                                        }
                                        MainForm.mainForm.Invoke(new EventHandler(delegate (Object sd, EventArgs ag)
                                        {
                                            Clipboard.SetText(copyText);
                                        }), new object[] { copyText });

                                        MessageBox.Show("复制手机剪切板信息成功,鼠标右键粘贴使用,信息:" + copyText, "拷贝手机剪贴板提示", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
                                        //MessageBox.Show("复制手机剪切板信息成功,鼠标右键粘贴使用,信息:" + copyText, "拷贝手机剪贴板提示", MessageBoxButtons.OKCancel);
                                    }
                                }
                                catch (Exception e)
                                {
                                    // 向用户显示出错消息
                                    //Console.WriteLine("The file could not be read:");
                                    //Console.WriteLine(e.Message);
                                    MessageBox.Show(""+e.ToString());
                                }
                            }

                        }
                    }
                   

                }
            });
        }



        public void buttonLeft()
        {
            int width = 480;
            int height = 800;
            if (slave.ScreenService.Width > 0)
            {
                width = slave.ScreenService.Width;
            }
            if (slave.ScreenService.Height > 0)
            {
                height = slave.ScreenService.Height;
            }
            int centerX = width / 2;
            int centerY = height / 2;
            int width4W = width / 4;
            int width8W = width / 8;
            int y1 = centerY;
            int y2 = centerY;
            int x2 = centerX - width4W;
            int x1 = centerX + width4W;
            Dispatcher.BackgroundThread(() =>
            {
                if (DeviceManager.isDeviceOnline(slave.Device.Serial))
                {
                    AdbManager.executeShellNoRead(slave.Device, "input swipe " + x1 + " " + y1 + " " + x2 + " " + y2);
                }
            }

            );
        }

        public void buttonUp()
        {


            int width = 480;
            int height = 800;
            if (slave.ScreenService.Width > 0)
            {
                width = slave.ScreenService.Width;
            }
            if (slave.ScreenService.Height > 0)
            {
                height = slave.ScreenService.Height;
            }
            int centerX = width / 2;
            int centerY = height / 2;
            int height4W = height / 4;
            int height8W = height / 8;
            int x1 = centerX;
            int x2 = centerX;
            int y1 = centerY + height4W;
            int y2 = centerY - height4W;
            Dispatcher.BackgroundThread(() =>
            {
                if (DeviceManager.isDeviceOnline(slave.Device.Serial))
                {
                    AdbManager.executeShellNoRead(slave.Device, "input swipe " + x1 + " " + y1 + " " + x2 + " " + y2);
                }
            }

            );
        }

        public void buttonRight()
        {

            int width = 480;
            int height = 800;
            if (slave.ScreenService.Width > 0)
            {
                width = slave.ScreenService.Width;
            }
            if (slave.ScreenService.Height > 0)
            {
                height = slave.ScreenService.Height;
            }
            int centerX = width / 2;
            int centerY = height / 2;
            int width4W = width / 4;
            int width8W = width / 8;
            int y1 = centerY;
            int y2 = centerY;
            int x1 = centerX - width4W;
            int x2 = centerX + width4W;
            Dispatcher.BackgroundThread(() =>
            {
                if (DeviceManager.isDeviceOnline(slave.Device.Serial))
                {
                    AdbManager.executeShellNoRead(slave.Device, "input swipe " + x1 + " " + y1 + " " + x2 + " " + y2);
                }
            }

            );
        }

        public void buttonDown()
        {
            int width = 480;
            int height = 800;
            if (slave.ScreenService.Width > 0)
            {
                width = slave.ScreenService.Width;
            }
            if (slave.ScreenService.Height > 0)
            {
                height = slave.ScreenService.Height;
            }
            int centerX = width / 2;
            int centerY = height / 2;
            int height4W = height / 4;
            int height8W = height / 8;
            int x1 = centerX;
            int x2 = centerX;
            int y2 = centerY + height4W;
            int y1 = centerY - height4W;
            Dispatcher.BackgroundThread(() =>
            {
                if (DeviceManager.isDeviceOnline(slave.Device.Serial))
                {
                    AdbManager.executeShellNoRead(slave.Device, "input swipe " + x1 + " " + y1 + " " + x2 + " " + y2);
                }
            }

            );
        }

        public void inputText(String text)
        {
            Dispatcher.BackgroundThread(() =>
            {
                if (DeviceManager.isDeviceOnline(slave.Device.Serial))
                {
                    InputMethodManager manger = new InputMethodManager();
                    manger.inputText(slave.Device, text);
                }
            }
            );
        }

        public void wakeUp()
        {
            Dispatcher.BackgroundThread(() =>
            {
                if (DeviceManager.isDeviceOnline(slave.Device.Serial))
                {
                    Boolean isOff = AdbDeviceManager.isScreenOff(slave.Device);
                    if (isOff)
                    {
                        AdbManager.executeShellNoRead(slave.Device, "input keyevent POWER");
                    }
                }
            }
            );
        }

        public void openLink(string linkUrl)
        {
            Dispatcher.BackgroundThread(() =>
            {
                if (DeviceManager.isDeviceOnline(slave.Device.Serial))
                {

                    //am start -a android.intent.action.VIEW -d ksnebula://live/play/"+liveid
                    AdbManager.executeShellNoRead(slave.Device, "am start -a  android.intent.action.VIEW -d "+linkUrl);
                    
                }
            }
           );
        }

        public void startDumpUI()
        {
            Dispatcher.BackgroundThread(() =>
            {
                if (DeviceManager.isDeviceOnline(slave.Device.Serial))
                {
                    string javapath = PathManager.getJavaPath();
                    //-Dfile.encoding=UTF-8
                    string pluginpath = PathManager.getPluginDir() + "\\uidump\\UIDump.jar";
                    string cmd = javapath + " -Dfile.encoding=UTF-8  -jar  " + pluginpath + " " + AdbManager.adbPath + " " + slave.Device.Serial;
                    AdbManager.ExecCmd(cmd);
                }
            }
          );
        }

        public  void startAppFromMonkey(string pkgName)
        {
            Dispatcher.BackgroundThread(() =>
            {
                if (DeviceManager.isDeviceOnline(slave.Device.Serial))
                {
                   
                        AdbManager.executeShellNoRead(slave.Device, "monkey -p "+pkgName+" -v 2");
                    
                }
            }
          );
        }
        //stopApp
        public void stopApp(string pkgName)
        {
            Dispatcher.BackgroundThread(() =>
            {
                if (DeviceManager.isDeviceOnline(slave.Device.Serial))
                {

                    AdbManager.executeShellNoRead(slave.Device, "am force-stop " + pkgName + "");

                }
            }
          );
        }


        public void  findMe()
        {
            Dispatcher.BackgroundThread(() =>
            {
                if (DeviceManager.isDeviceOnline(slave.Device.Serial))
                {

                    try
                    {
                        string cmd = "am  start -n   com.android.myinputmethod/com.github.uiautomator.FindMeActivity";
                        AdbManager.executeShellNoRead(slave.Device, cmd);
                    }catch(Exception eeeee)
                    {

                    }

                }
            }
         );
        }


      
       
        public void AddOutput(string line)
        {
            Debug.WriteLine(line);
        }

        public void Flush()
        {
        }
    }
}
